
package metamapp

import org.apache.log4j.Logger
import org.codehaus.groovy.grails.commons.ConfigurationHolder
import org.springframework.web.multipart.MultipartHttpServletRequest
import org.springframework.web.multipart.commons.CommonsMultipartFile
import util.ChemSimilarityUtil
import util.KEGGPairUtil
import util.ValidateUtil
import util.FileUtility

class KeggReactionPairController {

  Logger gLogger = Logger.getLogger(KeggReactionPairController.class)

  def index = {

    // MultipartHttpServletRequest is used to read attached files
    if (request instanceof MultipartHttpServletRequest) {

      MultipartHttpServletRequest mpr = (MultipartHttpServletRequest) request;

      def ActionVal = mpr.getAttribute("ActionVal")
      CommonsMultipartFile f
      CommonsMultipartFile inputKeggCID


      if (ActionVal == null || !ActionVal.toString().equalsIgnoreCase("Download")) {
        if (params.txtProbabilityFactor != null) {

          boolean isValidate = true
          if (mpr != null) {
            f = (CommonsMultipartFile) mpr.getFile("filePath");
            inputKeggCID = (CommonsMultipartFile) mpr.getFile("inputKeggCID");

          }

          flash.message = ""
          gLogger.info "============ Comming into index mathod of KEGGReactionPairController ================\n"
          gLogger.info "parmas.txtProbabilityFactor :: ${params.txtProbabilityFactor}"
          //gLogger.info "parmas.txtCSVData :: ${params.txtCSVData}"
          //gLogger.info "parmas.txtIdPairs :: ${params.txtIdPairs}"

          gLogger.info "parmas.filePath :: ${params.filePath}"
          gLogger.info "parmas.filePath.getClass :: ${params.filePath?.getClass()}"

          gLogger.info "inputKeggCID :: ${inputKeggCID}"
          gLogger.info "f :: ${f}"

          gLogger.info "inputKeggCID.empty :: ${inputKeggCID.empty}"

          if (inputKeggCID.empty && (params.txtIdPairs == null || params.txtIdPairs.toString().trim().length() == 0)) {
            isValidate = false
            flash.message = "Error! CID KEGG Id Pair pairs are mandatory."
            redirect(action: "index", params: params)
          } else
          if (!inputKeggCID.empty && !inputKeggCID.contentType.toString().equalsIgnoreCase("text/plain") && !inputKeggCID.contentType.toString().equalsIgnoreCase("application/save-to-disk") &&
                  !inputKeggCID.contentType.toString().equalsIgnoreCase("text/csv") && !inputKeggCID.contentType.toString().equalsIgnoreCase("application/vnd.ms-excel") ) {
            isValidate = false
            flash.message = "Error! Bad extension (contentType : ${inputKeggCID.contentType}), Upload only .csv or .txt extension file."
            redirect(action: "index", params: params)
          } else
          if (f.empty && (params.txtCSVData == null || params.txtCSVData.toString().trim().length() == 0)) {
            isValidate = false
            flash.message = "Error! Matrix Data is mandatory."
            redirect(action: "index", params: params)
          } else
          if (!f.empty && !f.contentType.toString().equalsIgnoreCase("text/plain") && !f.contentType.toString().equalsIgnoreCase("application/save-to-disk")
                  && !f.contentType.toString().equalsIgnoreCase("text/csv") && !f.contentType.toString().equalsIgnoreCase("application/vnd.ms-excel") ) {
            isValidate = false
            flash.message = "Error! Bad extension (contentType : ${f.contentType}), Upload only .csv or .txt extension file."
            redirect(action: "index", params: params)
          } else
          if (params.txtProbabilityFactor == null || !ValidateUtil.getInstance().isDouble(params.txtProbabilityFactor.toString())) {
            isValidate = false
            flash.message = "Error! ProbabilityFactor is mandatory and should be a decimal number"
            redirect(action: "index", params: params)
          } else {
            try {
              if (Double.parseDouble(params.txtProbabilityFactor) < 0.01 || Double.parseDouble(params.txtProbabilityFactor) > 1.0) {
                isValidate = false
                flash.message = "Error! Please enter Probability Factor between the range of 0.01 to 1.0"
                redirect(action: "index", params: params)
              }
            } catch (NumberFormatException e) {
              isValidate = false
              flash.message = "Error! Enter valid Probability Factor."
              redirect(action: "index", params: params)
            }
          }


          if (isValidate) {
            // Step:1 read attached file and prepare string out of it
            String keggReactionPair = "";
            if (!inputKeggCID.empty) {
              Reader reader = new InputStreamReader(inputKeggCID.getInputStream());
              keggReactionPair = FileUtility.getInstance().readFileStreamAsString(reader);
            }
            else {
              keggReactionPair = params.txtIdPairs.toString();
            }

            // process the request
            ArrayList<String> krpList = KEGGPairUtil.getInstance().processkeggReactionPair(keggReactionPair);
            session.setAttribute "krpResult", krpList

            // Step:2 read attached file and prepare string out of it
            String inputStr = "";
            if (!f.empty) {
              Reader reader = new InputStreamReader(f.getInputStream());
              inputStr = FileUtility.getInstance().readFileStreamAsString(reader);
            }
            else {
              inputStr = params.txtCSVData.toString();
            }

            session.setAttribute("SimilarityMatrixData",inputStr)
            session.setAttribute("ProbabilityFactor",params.txtProbabilityFactor)

            def fileName = f?.getOriginalFilename()
            // if file name is not there, give it to a default name
            if (fileName == null || fileName.trim().length() == 0) {
              fileName = "default"
            }

            // remove extension of the file
            if (fileName.toString().lastIndexOf(".") != -1) {
              fileName = fileName.toString().substring(0, fileName.toString().lastIndexOf("."))
            }

            // remove spaces from the filename if there any
            fileName = fileName.replaceAll(" ", "_");

            return [params:params,"fileName": fileName]
          }
        }

      }
    } else {

      // prepare result for export
      if (params.DownloadType != null) {
        gLogger.info '====================Dowmload Result==================='

        String appsType = params.DownloadType
        String networkApprochType = params.NetworkApprochType
        String resultStream = "";

        if (appsType != null) {

          String similarityMatrixData = null;

          if(session.getAttribute("SimilarityMatrixData")!=null){
             similarityMatrixData = session.getAttribute("SimilarityMatrixData")
          }

          Double probabilityFactor = null;
          if(session.getAttribute("ProbabilityFactor")!=null){
             probabilityFactor = Double.parseDouble(session.getAttribute("ProbabilityFactor").toString())
          }

          if (appsType.equalsIgnoreCase("KEGGReactionPair")) {

            List krpList = session.getAttribute("krpResult");
            String edgeAttributeStr = ChemSimilarityUtil.getInstance().processChemicalSimilarity(similarityMatrixData,probabilityFactor,networkApprochType,"SimilarityMap");
//			gLogger.info 'edgeAttributeStr : '+edgeAttributeStr;
//			gLogger.info 'krpList : '+krpList;
			
            resultStream = KEGGPairUtil.getInstance().prepareEdgeAttribute(edgeAttributeStr, krpList);

          }else{
              if( similarityMatrixData!=null && probabilityFactor!=null)
              {
                resultStream = ChemSimilarityUtil.getInstance().processChemicalSimilarity(similarityMatrixData,probabilityFactor,networkApprochType,appsType)
              }else{
                resultStream = "-No Result-"
              }
          }

          def fileName = params.fileName
          if (fileName == null) {
            fileName = "default"
          }

          response.contentType = ConfigurationHolder.config.grails.mime.types[params.format]
          response.setHeader("Content-disposition", "attachment; filename=${fileName}.${params.extension}")
          response.outputStream << resultStream
          response.outputStream.flush()
        }
      }
    }

  }

}
